package com.vadmin.vadminjava.common;

import com.alibaba.fastjson.JSONObject;
import com.mchange.v2.lang.StringUtils;
import com.vadmin.vadminjava.db.DBUtil;


import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Date;

/**
 * 反射注入Bean
 */
public class ResultSetToJavaBean {

    /**
     * 反射注入
     *
     * @param <T>
     * @param rs  ResultSet
     * @param obj java类的class
     * @return
     */
    public static <T> ArrayList<T> copy(ResultSet rs, Class<T> obj) {
        try {
            ArrayList<T> arrayList = new ArrayList<T>();
            ResultSetMetaData metaData = rs.getMetaData();
            /**
             * 获取总列数
             */
            int count = metaData.getColumnCount();
            while (rs.next()) {
                /**
                 * 创建对象实例
                 */
                T newInstance = obj.newInstance();
                for (int i = 1; i <= count; i++) {
                    /**
                     * 给对象的某个属性赋值
                     */
                    String name = metaData.getColumnName(i).toLowerCase();
                    name = toJavaField(name);// 改变列名格式成java命名格式
                    String substring = name.substring(0, 1);// 首字母大写
                    String replace = name.replaceFirst(substring, substring.toUpperCase());
                    Class<?> type;
                    try {
                        type = obj.getDeclaredField(name).getType();// 获取字段类型
                    } catch (Exception e) {
                        continue;
                    }
                    Method method = obj.getMethod("set" + replace, type);
                    /**
                     * 判断读取数据的类型
                     */
                    if (type.isAssignableFrom(String.class)) {
                        method.invoke(newInstance, rs.getString(i));
                    } else if (type.isAssignableFrom(int.class) || type.isAssignableFrom(Integer.class)) {
                        method.invoke(newInstance, rs.getInt(i));
                    } else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
                        method.invoke(newInstance, rs.getBoolean(i));
                    } else if (type.isAssignableFrom(Date.class)) {
                        method.invoke(newInstance, rs.getTimestamp(i));
                    } else if (type.isAssignableFrom(Double.class)) {
                        method.invoke(newInstance, rs.getDouble(i));
                    }
                }
                arrayList.add(newInstance);
            }
            return arrayList;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 数据库命名格式转java命名格式
     *
     * @param str 数据库字段名
     * @return java字段名
     */
    public static String toJavaField(String str) {

        String[] split = str.split("_");
        StringBuilder builder = new StringBuilder();
        builder.append(split[0]);// 拼接第一个字符

        // 如果数组不止一个单词
        if (split.length > 1) {
            for (int i = 1; i < split.length; i++) {
                // 去掉下划线，首字母变为大写
                String string = split[i];
                String substring = string.substring(0, 1);
                split[i] = string.replaceFirst(substring, substring.toUpperCase());
                builder.append(split[i]);
            }
        }
        return builder.toString();
    }

    /**
     * 功能描述: 反射注入JSON
     *
     * @param:
     * @return:
     * @auther:
     * @detail:
     * @date: 2020-05-08 10:06
     */
    public static ArrayList<JSONObject> copyJson(ResultSet rs) {
        ArrayList<JSONObject> arrayList = new ArrayList<JSONObject>();
        try {
            ResultSetMetaData metaData = rs.getMetaData();
            // 获取总列数
            int count = metaData.getColumnCount();
            while (rs.next()) {
                JSONObject obj = new JSONObject();
                for (int i = 1; i <= count; i++) {
                    // 给对象的某个属性赋值
                    String name = metaData.getColumnName(i).toLowerCase();
                    // 改变列名格式成java命名格式
                    name = toJavaField(name);
                    // 首字母大写
                    String substring = name.substring(0, 1);

                    String string = rs.getString(i);
                    obj.put(name, transferObject(string));
                }
                arrayList.add(obj);
            }
            return arrayList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return arrayList;
    }

    public static Object transferObject(String string) {
        Object pack = null;
        if (StringUtils.nonEmptyString(string)) {
            if (string.contains("{")) {
                //pack = JSONObject.parseObject(string); //先注释，因为目前项目要输出json文本，而不是一个对象
                pack = string;
            } else {
                pack = string;
            }
        }
        return pack;
    }

    public static ArrayList<JSONObject> copyJsonObj(ResultSet rs) {
        ArrayList<JSONObject> arrayList = new ArrayList<JSONObject>();
        try {
            ResultSetMetaData metaData = rs.getMetaData();
            // 获取总列数
            int count = metaData.getColumnCount();
            while (rs.next()) {
                JSONObject obj = new JSONObject();
                for (int i = 1; i <= count; i++) {
                    // 给对象的某个属性赋值
                    String name = metaData.getColumnName(i).toLowerCase();
                    // 改变列名格式成java命名格式
                    name = toJavaField(name);
                    // 首字母大写
                    String substring = name.substring(0, 1);
                    String replace = name.replaceFirst(substring, substring.toUpperCase());
                    obj.put(name, rs.getObject(i));
                }
                arrayList.add(obj);
            }
            return arrayList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return arrayList;
    }

    /**
     * 功能描述: 单个查询
     *
     * @param:
     * @return:
     * @auther:
     * @detail:
     * @date: 2020-05-08 10:06
     */
    public static JSONObject copyJsonSingleQuery(DBUtil dbUtil,String sql) {

        JSONObject obj = new JSONObject();
        try {
            ResultSet rs = dbUtil.executeQuery(sql);
            ResultSetMetaData metaData = rs.getMetaData();
            // 获取总列数
            int count = metaData.getColumnCount();
            if (rs.next()) {
                for (int i = 1; i <= count; i++) {
                    // 给对象的某个属性赋值
                    String name = metaData.getColumnName(i).toLowerCase();
                    // 改变列名格式成java命名格式
                    name = toJavaField(name);
                    // 首字母大写
                    String substring = name.substring(0, 1);
                    String replace = name.replaceFirst(substring, substring.toUpperCase());
                    String string = rs.getString(i);
                    obj.put(name, transferObject(string));
                }
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }


}
